home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / genial / func / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-14  |  17.6 KB  |  716 lines

  1.  
  2. /*
  3.  * file.c -- routines for loading and saving GENIAL images
  4.  *
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <fcntl.h>
  9. #include <strings.h>
  10. #include <rasterfile.h>
  11. #include <X11/Xlib.h>
  12.  
  13. #include "common.h"
  14. #include "ui.h"
  15. #include "display.h"
  16. #include "reg.h"
  17. #include "log.h"
  18. #include "file_ui.h"
  19.  
  20. #define READ_BLOCK_SIZE  524288    /* half a Meg... */
  21.  
  22. static int lmode = 0, smode = 0;/* load mode */
  23.  
  24. static int boxnum = 0;
  25. static file_rect_choice_win_objects *rect_win = NULL;    /* just a popup */
  26. FILE     *file_open(), *open_output_file();
  27.  
  28. set_lmode(m)
  29.     int       m;
  30. {
  31.     lmode = m;
  32. }
  33.  
  34. int
  35. load_image(fname)
  36.     char     *fname;
  37. {
  38.     FILE     *fp;
  39.     struct header hd;
  40.     int       i, remain;
  41.     unsigned  data_len;
  42.     int       name_loc, bytes_read;
  43.     char     *buffer;
  44.     char      msg[256], short_name[50];
  45.     XImage   *mk_x_img();
  46.  
  47.     if ((fp = file_open(fname)) == NULL)
  48.     return (-1);
  49.  
  50.     /* remove path name from file name if necessary */
  51.     name_loc = (int) rindex(fname, '/');
  52.     if (name_loc != NULL)
  53.     sprintf(short_name, "%s", name_loc + 1);
  54.     else
  55.     sprintf(short_name, "%s", fname);
  56.  
  57.     xv_set(base_win->image_fname, PANEL_LABEL_STRING, short_name, NULL);
  58.     panel_paint(base_win->image_fname, PANEL_CLEAR);
  59.  
  60.     if (lmode == 1) {
  61.     load_log_file(fname, fp);
  62.     return 1;
  63.     }
  64.     /* initialize the display structure */
  65.     if (orig_img == NULL) {
  66.     orig_img = (struct img_data *) malloc(sizeof(struct img_data));
  67.     bzero((char *) orig_img, sizeof(struct img_data));
  68.     } else {
  69.     /* free the data space from previous image */
  70.     free(orig_img->data);
  71.     free(orig_img->lut);
  72.     }
  73.  
  74.     /* read in HIPS header */
  75.     if (fread_header(fp, &hd, (Filename) fname) == HIPS_ERROR) {
  76.     XBell(display, 0);
  77.     fclose(fp);
  78.     return (-1);
  79.     }
  80.     orig_img->head = hd;
  81.  
  82.     switch (orig_img->head.pixel_format) {
  83.     case PFUINT:
  84.     orig_img->dsize = 4;
  85.     break;
  86.     case PFUSHORT:
  87.     orig_img->dsize = 2;
  88.     break;
  89.     case PFBYTE:
  90.     orig_img->dsize = 1;
  91.     break;
  92.     default:
  93.     XBell(display, 0);
  94.     fprintf(stderr, "Data type not currently understood.\n");
  95.     return (-1);
  96.     }
  97.  
  98.     orig_img->width = orig_img->head.ocols;
  99.     orig_img->height = orig_img->head.orows;
  100.     orig_img->nframes = orig_img->head.num_frame;
  101.     orig_img->comment = orig_img->head.seq_desc;
  102.     orig_img->cframe = 1;
  103.     orig_img->file_saved = 0;
  104.     data_len = (unsigned) (orig_img->width * orig_img->height *
  105.                orig_img->nframes);
  106.     if ((buffer = (char *) calloc(data_len, orig_img->dsize)) == NULL) {
  107.     sprintf(msg, "Error allocating storage:");
  108.     (void) strcat(msg, sys_errlist[errno]);
  109.     lab_info(msg, 1);
  110.     fprintf(stderr, "%s\n", msg);
  111.     return (-1);
  112.     }
  113. #define SIMPLER
  114. #ifdef SIMPLER
  115.     fprintf(stderr, "genial: Loading image...... \n");
  116.     if (fread(buffer, orig_img->dsize, data_len, fp) != data_len) {
  117.     XBell(display, 0);
  118.     perror("\n error reading data\n");
  119.     return (-1);
  120.     }
  121.     orig_img->data = buffer;
  122. #else
  123.     /*
  124.      * NOTE!! There is a bug here that causes a segv on certain sized
  125.      * images!! (ex: 480x512)
  126.      */
  127.     orig_img->data = buffer;
  128.     /* read in the image a fraction at a time... */
  129.     for (i = 0; (unsigned) (i * READ_BLOCK_SIZE) < data_len; i++) {
  130.     bytes_read = fread(buffer, orig_img->dsize, READ_BLOCK_SIZE, fp);
  131.     if ((bytes_read < 0) ||
  132.         (data_len * orig_img->dsize < READ_BLOCK_SIZE &&
  133.          bytes_read != data_len * orig_img->dsize)) {
  134.         XBell(display, 0);
  135.         sprintf(msg, "Error reading image from file:");
  136.         (void) strcat(msg, sys_errlist[errno]);
  137.         lab_info(msg, 1);
  138.         fprintf(stderr, "%s\n", msg);
  139.         return (-1);
  140.     }
  141.     sprintf(msg, "Loading image: %d%% loaded",
  142.         (int) (i * READ_BLOCK_SIZE) * 100 / data_len);
  143.     lab_info(msg, 1);
  144.     printf("%s\n", msg);
  145.  
  146.     buffer += (READ_BLOCK_SIZE * orig_img->dsize);
  147.     }
  148.     remain = data_len - (--i * READ_BLOCK_SIZE);
  149.     if (fread(buffer, orig_img->dsize, remain, fp) < 0) {
  150.     sprintf(msg, "Error reading image from file:");
  151.     XBell(display, 0);
  152.     (void) strcat(msg, sys_errlist[errno]);
  153.     lab_info(msg, 1);
  154.     fprintf(stderr, "%s\n", msg);
  155.     return (-1);
  156.     }
  157. #endif
  158.     (void) xv_set(img_win->d_win, FRAME_MAX_SIZE,
  159.               orig_img->width + SCROLL_BAR_SIZE,
  160.                     orig_img->height + SCROLL_BAR_SIZE, NULL);
  161.  
  162.  
  163.     sprintf(msg, "Loading image: %d%% loaded", 100);
  164.     lab_info(msg, 1);
  165.     printf("%s\n", msg);
  166.  
  167.     /* create lut buffer with size of 1 frame */
  168.     if (depth == 24)
  169.     buffer = (char *) calloc(orig_img->width * orig_img->height * 4,
  170.                  sizeof(byte));
  171.     else
  172.     buffer = (char *) calloc(orig_img->width * orig_img->height,
  173.                  sizeof(byte));
  174.     if (buffer == NULL) {
  175.     sprintf(msg, "Error allocating storage:");
  176.     (void) strcat(msg, sys_errlist[errno]);
  177.     lab_info(msg, 1);
  178.     fprintf(stderr, "%s\n", msg);
  179.     return (-1);
  180.     }
  181.     orig_img->lut = buffer;
  182.  
  183.     printf("Finding extrema.  Linear scan 1 of 3:");
  184.     fflush(stdout);
  185.     /* find extrema of image */
  186.     extrema(orig_img);
  187.     putchar('\n');
  188.  
  189.     /* initialize the display */
  190.     init_display(orig_img);
  191.  
  192.     printf("Building colormap.... ");
  193.     fflush(stdout);
  194.     build_cmap(orig_img);    /* sets orig_img->lut */
  195.  
  196.     printf("Building original XImage.  Linear scan 2 of 3:");
  197.     fflush(stdout);
  198.     /* make an XImage */
  199.     orig_ximg = mk_x_img(orig_img, orig_ximg, 0);
  200.     putchar('\n');
  201.  
  202.     printf("Building display XImage.  Linear scan 3 of 3:");
  203.     fflush(stdout);
  204.     disp_ximg = mk_x_img(orig_img, disp_ximg, 1);
  205.     putchar('\n');
  206.  
  207.     printf("Displaying image.\n");
  208.     disp_img();
  209.  
  210.     printf("Loading log.\n");
  211.     read_log(&orig_img->head);
  212.     printf("Loading complete\n");
  213.     return 1;
  214. }
  215.  
  216. /***************************************************************/
  217. FILE     *
  218. file_open(fname)
  219.     char     *fname;
  220. {
  221.     FILE     *fp;
  222.     char      msg[256];
  223.  
  224.     if ((fp = fopen(fname, "r")) == NULL) {
  225.     sprintf(msg, "Error opening:%s: ", fname);
  226.     (void) strcat(msg, sys_errlist[errno]);
  227.     XBell(display, 0);
  228.     lab_info(msg, 1);
  229.     fprintf(stderr, "%s\n", msg);
  230.     }
  231.     return (fp);
  232. }
  233.  
  234. /***************************************************************/
  235.  
  236. load_log_file(fname, fp)
  237.     char     *fname;
  238.     FILE     *fp;
  239. {
  240.     struct header hd;
  241.  
  242.     /* read in HIPS header */
  243.     if (fread_header(fp, &hd, (Filename) fname) == HIPS_ERROR) {
  244.     XBell(display, 0);
  245.     fclose(fp);
  246.     return (-1);
  247.     }
  248.     printf("Loading log.\n");
  249.     read_log(&hd);
  250.     printf("Loading complete\n");
  251.  
  252.     return 1;
  253. }
  254.  
  255. /********************************************************/
  256. #define getbytes(c,n) ( *((unsigned *) (c)) >> (8*(4-n)))
  257.  
  258. extrema(ras)
  259.     struct img_data *ras;
  260. {
  261.     unsigned  minv, maxv;
  262.     register unsigned j;
  263.     register int i;
  264.  
  265.     /* find minima and maxima */
  266.     minv = (unsigned long) getbytes(ras->data, ras->dsize);
  267.     maxv = 0;
  268.     if (ras->dsize == 1) {
  269.     for (i = 0; i < ras->height * ras->width; i++) {
  270.         j = *((unsigned char *) ras->data + i);
  271.         if (j > maxv)
  272.         maxv = j;
  273.         else if (j < minv)
  274.         minv = j;
  275.     }
  276.     } else if (ras->dsize == 2) {
  277.     for (i = 0; i < (ras->height * ras->width); i++) {
  278.         j = *((unsigned short *) ras->data + i);
  279.         if (j > maxv)
  280.         maxv = j;
  281.         else if (j < minv)
  282.         minv = j;
  283.     }
  284.     } else if (ras->dsize == 4) {
  285.     for (i = 0; i < ras->height * ras->width; i += 4) {
  286.         j = *((unsigned int *) ras->data + i);
  287.         if (j > maxv)
  288.         maxv = j;
  289.         else if (j < minv)
  290.         minv = j;
  291.     }
  292.     }
  293.     ras->maxv = maxv;
  294.     ras->minv = minv;
  295. }
  296.  
  297. int
  298. set_smode(m)
  299.     int       m;
  300. {
  301.     smode = m;
  302. }
  303.  
  304. save_image(fname, item)
  305.     char     *fname;
  306.     Panel_item item;
  307. {
  308.     FILE     *fp;
  309.     char     *data_ptr;
  310.  
  311.     fp = open_output_file(fname);
  312.  
  313.     if (smode == 4) {
  314.     save_rasterfile(fp);
  315.     return 1;
  316.     }
  317.     if (smode == 5) {
  318.     save_trace_vector(fp);
  319.     return 1;
  320.     }
  321.     if (smode == 6) {
  322.     save_histogram_vector(fp);
  323.     return 1;
  324.     }
  325.     if (smode == 0 || smode == 3) {
  326.     save_log(&orig_img->head);
  327.     }
  328.     if (smode == 2) {
  329.     if (rect_win == NULL) {
  330.         rect_win = file_rect_choice_win_objects_initialize(NULL,
  331.                              file_win->window1);
  332.     }
  333.     set_rect_panel_state();
  334.     xv_set(rect_win->rect_choice_win,
  335.            XV_SHOW, TRUE,
  336.            FRAME_CLOSED, FALSE, NULL);
  337.     return 1;
  338.     }
  339.     orig_img->head.seq_desc = orig_img->comment;
  340.     orig_img->head.sizedesc = strlen(orig_img->comment);
  341.     fwrite_header(fp, &orig_img->head, fname);
  342.     orig_img->file_saved = 1;
  343.  
  344.     if (smode == 3) {        /* mode 3 is header only */
  345.     fclose(fp);
  346.     return 0;
  347.     }
  348.     /* set data_ptr to beginning of first frame */
  349.     if (orig_img->cframe != 1)
  350.     data_ptr = (char *) (orig_img->data - ((orig_img->cframe - 1) *
  351.            (orig_img->width * orig_img->height * orig_img->dsize)));
  352.     else
  353.     data_ptr = (char *) orig_img->data;
  354.  
  355.     if (fwrite(data_ptr, orig_img->dsize,
  356.     orig_img->width * orig_img->height * orig_img->nframes, fp) == -1) {
  357.     XBell(display, 0);
  358.     perror("write:");
  359.     fclose(fp);
  360.     return -1;
  361.     }
  362.     fclose(fp);
  363.     return 0;
  364. }
  365.  
  366. /* the following routines are for use with saving rectangular subimages */
  367.  
  368. /* set_rect_panel_state() sets the appropriate items as valid or invalid */
  369. set_rect_panel_state()
  370. {
  371.     struct logent *ent, *log_by_id();
  372.  
  373.     ent = log_by_id(boxnum);
  374.     if (ent == NULL) {
  375.     xv_set(rect_win->box_save,
  376.            PANEL_INACTIVE, TRUE,
  377.            NULL);
  378.     return;
  379.     }
  380.     if (ent->reg) {
  381.     if (ent->reg->r_type != BOX) {
  382.         xv_set(rect_win->box_save,
  383.            PANEL_INACTIVE, TRUE,
  384.            NULL);
  385.         return;
  386.     }
  387.     } else {
  388.     xv_set(rect_win->box_save,
  389.            PANEL_INACTIVE, TRUE,
  390.            NULL);
  391.     return;
  392.     }
  393.     /* it really is a valid box, so set the save button */
  394.     xv_set(rect_win->box_save,
  395.        PANEL_INACTIVE, FALSE,
  396.        NULL);
  397. }
  398.  
  399. /*
  400.  * Notify callback function for `box_lid'.
  401.  */
  402. Panel_setting
  403. boxid_proc(item, event)
  404.     Panel_item item;
  405.     Event    *event;
  406. {
  407.     int       value = (int) xv_get(item, PANEL_VALUE);
  408.  
  409.     boxnum = value;
  410.     set_rect_panel_state();
  411.     return panel_text_notify(item, event);
  412. }
  413.  
  414. /*
  415.  * Notify callback function for `box_cancel'.
  416.  */
  417. void
  418. box_cancel_proc(item, event)
  419.     Panel_item item;
  420.     Event    *event;
  421. {
  422.     xv_set(rect_win->rect_choice_win, XV_SHOW, FALSE, NULL);
  423. }
  424.  
  425.  
  426. /*
  427.  * Notify callback function for `box_save'.
  428.  * this does the actual saving
  429.  */
  430. void
  431. box_save_proc(item, event)
  432.     Panel_item item;
  433.     Event    *event;
  434. {
  435.     char     *fname = (char *) xv_get(file_win->s_fname, PANEL_VALUE);
  436.     struct header newhead;
  437.     struct logent *ent, *log_by_id();
  438.     char      msg[80];
  439.     XPoint    p1, p2;
  440.     char     *data;
  441.     FILE     *fp;
  442.     int       rows, cols, x, y;
  443.  
  444.     ent = log_by_id(boxnum);
  445.     if (ent == NULL) {
  446.     (void) notice_prompt(rect_win->controls2, NULL,
  447.                  NOTICE_FOCUS_XY, event_x(event), event_y(event),
  448.                  NOTICE_MESSAGE_STRINGS,
  449.             "Selected log entry is not a valid rectangle", NULL,
  450.                  NOTICE_BUTTON_YES, "OK",
  451.                  NULL);
  452.     return;
  453.     }
  454.     if (ent->reg) {
  455.     if (ent->reg->r_type != BOX) {
  456.         (void) notice_prompt(rect_win->controls2, NULL,
  457.                 NOTICE_FOCUS_XY, event_x(event), event_y(event),
  458.                  NOTICE_MESSAGE_STRINGS,
  459.             "Selected log entry is not a valid rectangle", NULL,
  460.                  NOTICE_BUTTON_YES, "OK",
  461.                  NULL);
  462.         return;
  463.     }
  464.     } else {
  465.     (void) notice_prompt(rect_win->controls2, NULL,
  466.                  NOTICE_FOCUS_XY, event_x(event), event_y(event),
  467.                  NOTICE_MESSAGE_STRINGS,
  468.             "Selected log entry is not a valid rectangle", NULL,
  469.                  NOTICE_BUTTON_YES, "OK",
  470.                  NULL);
  471.     return;
  472.     }
  473.  
  474.     /* its a valid box number, so lets do it */
  475.  
  476.     fp = open_output_file(fname);
  477.  
  478.     bcopy((char *) &orig_img->head, (char *) &newhead, sizeof(struct header));
  479.  
  480.     p1.x = ent->reg->r_plist->pt.x;
  481.     p1.y = ent->reg->r_plist->pt.y;
  482.     p2.x = ent->reg->r_plist->next->pt.x;
  483.     p2.y = ent->reg->r_plist->next->pt.y;
  484.  
  485.     cols = p2.x - p1.x;
  486.     rows = p2.y - p1.y;
  487.     newhead.orows = newhead.rows = rows;
  488.     newhead.ocols = newhead.cols = cols;
  489.     newhead.num_frame = 1;
  490.  
  491.     data = malloc(rows * cols * orig_img->dsize);
  492.     switch (orig_img->dsize) {
  493.     case 1:
  494.     for (y = p1.y; y < p2.y; y++)
  495.         for (x = p1.x; x < p2.x; x++)
  496.         *(data + ((y - p1.y) * cols * orig_img->dsize) + (x - p1.x)) =
  497.             (char) dval(x, y, orig_img, 0);
  498.     break;
  499.     case 2:
  500.     for (y = p1.y; y < p2.y; y++)
  501.         for (x = p1.x; x < p2.x; x++)
  502.         *((u_short *) data + ((y - p1.y) * cols + (x - p1.x))) =
  503.             (u_short) dval(x, y, orig_img, 0);
  504.     break;
  505.     case 4:
  506.     for (y = p1.y; y < p2.y; y++)
  507.         for (x = p1.x; x < p2.x; x++)
  508.         *((u_int *) data + ((y - p1.y) * cols + (x - p1.x))) =
  509.             (u_int) dval(x, y, orig_img, 0);
  510.     break;
  511.     }
  512.  
  513.     fwrite_header(fp, &newhead, fname);
  514.     if (fwrite(data, rows * cols, orig_img->dsize, fp) < 1) {
  515.     XBell(display, 0);
  516.     sprintf(msg, "Error writing:%s: ", fname);
  517.     (void) strcat(msg, sys_errlist[errno]);
  518.     lab_info(msg, 1);
  519.     fprintf(stderr, "%s\n", msg);
  520.     return;
  521.     }
  522.     fclose(fp);
  523. }
  524.  
  525. /***********************************************************************/
  526.  
  527. save_trace_vector(fp)
  528.     FILE     *fp;
  529. {
  530.     char     *buffer, tstr[80];
  531.     struct logent *tmp;
  532.     struct trcontext *trace;
  533.     int       log_size = 1000;
  534.     struct header hd;
  535.     int i, cnt=0;
  536.  
  537.     buffer = (char *) calloc(log_size, 1);
  538.  
  539.     for (tmp = loghead; tmp != NULL && tmp->reg != NULL; tmp = tmp->next) {
  540.     trace = tmp->trace;
  541.     if (trace != NULL) {
  542.         sprintf(tstr, "Trace # %d \n", cnt++);
  543.         for (i = 0; i < trace->npts; i++) {
  544.         sprintf(tstr, "%d %d %d \n", trace->pbuf[i].pt.x,
  545.             trace->pbuf[i].pt.y, trace->pbuf[i].oval);
  546.         strcat(buffer, tstr);
  547.         if (strlen(buffer) > log_size - 50) {
  548.             log_size += 1000;
  549.             buffer = (char *) realloc(buffer, log_size);
  550.         }
  551.         }
  552.     }
  553.     }
  554.  
  555.     init_header(&hd, "genial-trace", "", 0, "", 0, 0, PFASCII, 1, "");
  556.     setparam(&hd, "Genial-Trace", PFASCII, strlen(buffer) + 1, buffer);
  557.     fwrite_header(fp, &hd, "genial trace log");
  558.     fclose(fp);
  559. }
  560.  
  561. /***********************************************************************/
  562.  
  563. save_histogram_vector(fp)
  564.     FILE     *fp;
  565. {
  566.     char     *buffer, tstr[80];
  567.     struct logent *tmp;
  568.     struct hcontext *histo;
  569.     int       log_size = 1000;
  570.     struct header hd;
  571.     int i, cnt=0;
  572.  
  573.   /* maybe should be using HIPS histogram format (PFHIST) */
  574.  
  575.     buffer = (char *) calloc(log_size, 1);
  576.  
  577.     for (tmp = loghead; tmp != NULL && tmp->reg != NULL; tmp = tmp->next) {
  578.     histo = tmp->hist;
  579.     if (histo != NULL) {
  580.         sprintf(tstr, "Histogram # %d \n", cnt++);
  581.         for (i = 0; i < NUM_BUCKETS; i++) {
  582.         sprintf(tstr, "%d ", histo->countvec[i]);
  583.         strcat(buffer, tstr);
  584.         if (strlen(buffer) > log_size - 30) {
  585.             log_size += 1000;
  586.             buffer = (char *) realloc(buffer, log_size);
  587.         }
  588.         }
  589.         strcat(buffer, "\n");
  590.     }
  591.     }
  592.  
  593.     init_header(&hd, "genial-histogram", "", 0, "", 0, 0, PFASCII, 1, "");
  594.     setparam(&hd, "Genial-Histogram", PFASCII, strlen(buffer) + 1, buffer);
  595.     fwrite_header(fp, &hd, "genial histogram");
  596.     fclose(fp);
  597. }
  598.  
  599. /***********************************************************************/
  600.  
  601. save_rasterfile(fp)
  602.     FILE     *fp;
  603. {
  604.     struct rasterfile sunheader;
  605.     int       i, y, nc, linesize;
  606.     char     *line;
  607.     XImage   *ximage;
  608.     Window    win;
  609.     Pixmap    pixmap;
  610.     XColor    color_table[256];
  611.     byte      rmap[256], gmap[256], bmap[256];
  612.  
  613.     win = RootWindow(display, DefaultScreen(display));
  614.     pixmap = XCreatePixmap(display, win, orig_img->width, orig_img->height, 8);
  615.     XCopyArea(display, img_win->d_xid, pixmap, gc, 0, 0,
  616.           orig_img->width, orig_img->height, 0, 0);
  617.  
  618.     if (!(ximage = XGetImage(display, pixmap, 0, 0, orig_img->width,
  619.                  orig_img->height, (~0), ZPixmap))) {
  620.     fprintf(stderr, "Error: XGetImage failed \n");
  621.     return (-1);
  622.     }
  623.     /*
  624.      * we could get fancy here and find only the colormap entries which are
  625.      * used, and redo the ximage->data entries to reflect the compressed
  626.      * colormap, but this works OK for now...  -BT
  627.      */
  628.  
  629.     nc = 256;
  630.     for (i = 0; i < 256; i++) {
  631.     color_table[i].pixel = (unsigned long) i;
  632.     }
  633.  
  634.     XQueryColors(display, XDefaultColormap(display, DefaultScreen(display)),
  635.          color_table, nc);    /* fills in color_table entries */
  636.  
  637.     for (i = 0; i < 256; i++) {
  638.     rmap[i] = (byte) (color_table[i].red);
  639.     gmap[i] = (byte) (color_table[i].green);
  640.     bmap[i] = (byte) (color_table[i].blue);
  641. #ifdef DEBUG
  642.     fprintf(stderr, "color map entry (%d): r: %d, g: %d, b: %d \n",
  643.         i, (int) rmap[i], (int) gmap[i], (int) bmap[i]);
  644. #endif
  645.     }
  646.     linesize = orig_img->width;
  647.     if (linesize % 2)
  648.     linesize++;
  649.     line = (char *) malloc(linesize);
  650.  
  651.     /* fill in Sun rasterfile header */
  652.     sunheader.ras_magic = RAS_MAGIC;
  653.     sunheader.ras_width = orig_img->width;
  654.     sunheader.ras_height = orig_img->height;
  655.     sunheader.ras_depth = 8;
  656.     sunheader.ras_length = linesize * orig_img->height;
  657.     sunheader.ras_type = RT_STANDARD;
  658.     sunheader.ras_maptype = RMT_EQUAL_RGB;
  659.     sunheader.ras_maplength = 3 * nc;
  660.     fwrite(sunheader, sizeof(struct rasterfile), 1, fp);
  661.  
  662.     fwrite(rmap, sizeof(byte), nc, fp);
  663.     fwrite(gmap, sizeof(byte), nc, fp);
  664.     fwrite(bmap, sizeof(byte), nc, fp);
  665.  
  666.     /* write the image */
  667.     line[linesize - 1] = 0;
  668.     for (y = 0; y < orig_img->height; y++) {
  669.  
  670.     memcpy(line, ximage->data + y * ximage->bytes_per_line, orig_img->width);
  671.  
  672.     if (fwrite(line, sizeof(char), linesize, fp) != linesize) {
  673.         free(line);
  674.         return (-1);
  675.     }
  676.     }
  677.     free(line);
  678.  
  679.     fclose(fp);
  680.     return (0);
  681. }
  682.  
  683. /*************************************************************/
  684.  
  685. FILE     *
  686. open_output_file(fname)
  687.     char     *fname;
  688. {
  689.     FILE     *fp;
  690.     char      msg[80];
  691.     int       result;
  692.     Panel     panel = (Panel) xv_get(file_win->save, PANEL_PARENT_PANEL, NULL);
  693.  
  694.     if ((fp = fopen(fname, "r")) != NULL) {
  695.     fclose(fp);
  696.     result = notice_prompt(panel, NULL,
  697.                    NOTICE_MESSAGE_STRINGS,
  698.                    "Overwrite existing file?", NULL,
  699.                    NOTICE_BUTTON_YES, "Yes",
  700.                    NOTICE_BUTTON_NO, "No",
  701.                    NULL);
  702.  
  703.     if (result == NOTICE_NO)
  704.         return (NULL);
  705.     }
  706.     if ((fp = fopen(fname, "w")) == NULL) {
  707.     sprintf(msg, "Error opening:%s: ", fname);
  708.     XBell(display, 0);
  709.     (void) strcat(msg, sys_errlist[errno]);
  710.     lab_info(msg, 1);
  711.     fprintf(stderr, "%s\n", msg);
  712.     return (NULL);
  713.     }
  714.     return (fp);
  715. }
  716.